package cn.ray.springframework.beans.factory.support;

import cn.ray.springframework.beans.BeansException;
import cn.ray.springframework.beans.factory.FactoryBean;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


//负责管理和缓存由FactoryBean创建出来的对象
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {

    //用于存放单例类型的对象，避免重复创建
    //类似于Redis与Mysql的关系，cache中查不到，才去真的创建
    private final Map<String ,Object> factoryBeanObjectCache=new ConcurrentHashMap<>();

    protected Object getCachedObjectForFactoryBean(String beanName){
        //根据beanName获取已经创建的FactoryBean产生的对象
        Object object=this.factoryBeanObjectCache.get(beanName);
        //NULL_OBJECT表示：我们已经调用过getObject，返回了null
        return object!=NULL_OBJECT?object:null;
    }

    //从factoryBean获取目标对象
    protected Object getObjectFromFactoryBean(FactoryBean factory,String beanName){
        if(factory.isSingleton()){
            Object object=this.factoryBeanObjectCache.get(beanName);
            if(object==null){
                object=doGetObjectFromFactoryBean(factory,beanName);
                this.factoryBeanObjectCache.put(beanName,(object!=null?object:NULL_OBJECT));
            }
            return (object!=NULL_OBJECT?object:null);
        }
        else{
            return doGetObjectFromFactoryBean(factory,beanName);
        }
    }

    private Object doGetObjectFromFactoryBean(FactoryBean factory, String beanName) {
        try{
            return factory.getObject();
        } catch (Exception e) {
            throw new BeansException("FactoryBean threw exception on object[" + beanName + "] creation", e);
        }
    }

}
